package com.ucode.sys.service.impl;

import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ucode.sys.mapper.DeptMapper;
import com.ucode.sys.mapper.UserMapper;
import com.ucode.sys.model.Dept;
import com.ucode.sys.model.User;
import com.ucode.sys.service.UserService;
import com.ucode.sys.vo.UserVo;
import com.ucode.tool.base.Paginator;
import com.ucode.tool.base.ResultCodeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.util.IdentifyUtils;
import cn.hutool.core.util.StrUtil;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DeptMapper deptMapper;
    
    @Override
    @Transactional
    public User insert(User user) {
        Date now = new Date();
        user.setId(IdentifyUtils.getDefaultSnowflakeId());
        user.setCreatedTime(now);
        user.setUpdatedTime(now);
        int i = userMapper.insert(user);
        //分析失败原因,给调用端已知的异常信息
        if(i == 0){
            if(userMapper.findByMobile(user.getMobile()) != null){
                throw new UcodeServiceException(ResultCodeEnum.MOBILE_REPEAT.code, ResultCodeEnum.MOBILE_REPEAT.message);
            }else if(userMapper.findByUsername(user.getUsername()) != null){
                throw new UcodeServiceException(ResultCodeEnum.USERNAME_REPEAT.code, ResultCodeEnum.USERNAME_REPEAT.message);
            }else if(userMapper.findByEmail(user.getEmail()) != null){
                throw new UcodeServiceException(ResultCodeEnum.EMAIL_REPEAT.code, ResultCodeEnum.EMAIL_REPEAT.message);
            }
        }
        return i > 0 ? user : null;
    }

    @Override
    public int update(User user) {
        User old = userMapper.findById(user.getId());
        if(old == null) return 0;
        try{
            return userMapper.update(user);
        }catch(DuplicateKeyException e){
            //捕捉唯一约束异常,解析分析失败原因,给调用端已知的异常信息
            if(StrUtil.isNotBlank(user.getMobile()) && !user.getMobile().equals(old.getMobile())
                    && userMapper.findByMobile(user.getMobile()) != null){
                throw new UcodeServiceException(ResultCodeEnum.MOBILE_REPEAT.code, ResultCodeEnum.MOBILE_REPEAT.message);
            }else if(StrUtil.isNotBlank(user.getUsername()) && !user.getUsername().equals(old.getUsername())
                    && userMapper.findByUsername(user.getUsername()) != null){
                throw new UcodeServiceException(ResultCodeEnum.USERNAME_REPEAT.code, ResultCodeEnum.USERNAME_REPEAT.message);
            }else if(StrUtil.isNotBlank(user.getEmail()) && !user.getEmail().equals(old.getEmail())
                    && userMapper.findByEmail(user.getEmail()) != null){
                throw new UcodeServiceException(ResultCodeEnum.EMAIL_REPEAT.code, ResultCodeEnum.EMAIL_REPEAT.message);
            }else{
                throw new RuntimeException(e.getMessage());
            }
        }
    }
    @Override
    public int resetUsername(Long id, String username, String password) {
        try{
            return userMapper.resetUsername(id, username, password);
        }catch(DuplicateKeyException e){
            throw new UcodeServiceException(ResultCodeEnum.USERNAME_REPEAT.code, ResultCodeEnum.USERNAME_REPEAT.message);
        }
    }
    
    @Override
    public int updatePassword(List<Long> ids, String password) {
        return userMapper.batchUpdatePassword(ids, password);
    }

    @Override
    public int updatePassword(Long id, String password) {
        return userMapper.updatePassword(id, password);
    }
    
    @Override
    public int updateStatuz(List<Long> ids, Integer statuz) {
        return userMapper.updateStatuz(ids, statuz);
    }

    @Override
    public User findById(Long id) {
        return userMapper.findById(id);
    }
    
    @Override
    public List<User> findByIds(List<Long> ids) {
        return userMapper.findByIds(ids);
    }

    @Override
    public User findByMobile(String mobile) {
        return userMapper.findByMobile(mobile);
    }

    @Override
    public User findByEmail(String email) {
        return userMapper.findByEmail(email);
    }

    @Override
    public User findByUsername(String username) {
        return userMapper.findByUsername(username);
    }

    @Override
    public User findByMEA(String mea) {
        return userMapper.findByMEA(mea);
    }

    @Override
    public Paginator<UserVo> queryPage(String realname, String username, String mobile, Long deptId, Integer statuz, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<UserVo> users = userMapper.queryList(realname, username, mobile, deptId, statuz);
        PageInfo<UserVo> pageInfo = new PageInfo<>(users);
        return new Paginator<>(pageInfo.getTotal(), pageInfo.getPageNum(), pageInfo.getPageSize(), users);
    }

    @Override
    public Paginator<UserVo> queryPageRoleUsers(Long roleId, String realname, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<UserVo> users = userMapper.queryRoleUserList(roleId, realname);
        PageInfo<UserVo> pageInfo = new PageInfo<>(users);
        return new Paginator<>(pageInfo.getTotal(), pageInfo.getPageNum(), pageInfo.getPageSize(), users);
    }

    @Override
    public List<Long> findDirectSubordinateUserIds(Long userId) {
        return userMapper.findDirectSubordinateUserIds(userId);
    }
    
    @Override
    public int findDeptDirectUserCount(Long deptId) {
        return userMapper.findDeptDirectUserCount(deptId);
    }

    @Override
    public List<Long> findDeptDirectUserIds(List<Long> deptIds) {
        return userMapper.findDeptDirectUserIds(deptIds);
    }

    @Override
    public List<Long> findDeptAllUserIds(Long deptId) {
        Dept dept = deptMapper.findById(deptId);
        if(dept != null){
            String ancestorsPrefix = StrUtil.concat(true,dept.getAncestors(), "," ,dept.getId().toString(),"%");
            return userMapper.findDeptAndAllChildsUserIds(deptId, ancestorsPrefix);
        }
        return null;
    }

}
